home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / modelers / geomview / source.lha / Geomview / src / lib / geomutil / plutil / anytopl.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-02-08  |  9.4 KB  |  374 lines

  1. /*
  2.  * anytopl.c
  3.  * author:  Celeste Fowler
  4.  * date:  June 12, 1992
  5.  */
  6. #include <stdlib.h>
  7. #include "polylistP.h"
  8. #include "bezierP.h"
  9. #include "quadP.h"
  10. #include "meshP.h"
  11. #include "vectP.h"
  12. #include "listP.h"
  13. #include "discgrpP.h"
  14. #include "instP.h"
  15. #include "hpoint3.h"
  16. #include "point3.h"
  17. #include "plutil.h"
  18.  
  19. static char msg[] = "anytopl.c";
  20.  
  21. void PLTransformInto(PolyList *src, PolyList *dest, Transform T);
  22.  
  23. /*
  24.  * AnyToPL converter.
  25.  * Converts any geomview object to an polylist and returns a pointer
  26.  * to the polylist.  Should return a consolidated polylist, but right
  27.  * now, for the sake of convenience, does not.  NB to future
  28.  * developers: There are a lot of assumptions about the internals of
  29.  * the various data types.  If anything changes, things will have to
  30.  * be adjusted accordingly.
  31.  */
  32.  
  33. Geom *AnyToPL(Geom *old, Transform T) 
  34. {  
  35.   char *oldtype;
  36.   int g, h, i, j, k;
  37.   HPoint3 *point4 = NULL;
  38.   ColorA *color = NULL;
  39.   Point3 *normal = NULL;
  40.   int npoly = 0;
  41.   int *nvert = NULL, *vert = NULL;
  42.   PolyList *new = NULL;
  43.   int flags = 0;
  44.   int transpts = 1;
  45.   int fourd = 0;
  46.  
  47.   if (old == NULL) return NULL;
  48.   oldtype = GeomName(old);
  49.   
  50.   /* 
  51.    * PolyList to PolyList 
  52.    */
  53.   if (!strcmp(oldtype, "polylist")) {
  54.     new = (PolyList *) GeomCopy(old);
  55.     flags = new->flags;
  56.   }
  57.   
  58.  
  59.   /*
  60.    * Bezier to PolyList
  61.    */
  62.   if (!strcmp(oldtype, "bezier")) {
  63.     Bezier *b = (Bezier *)old;
  64.  
  65.     if ((b->mesh == NULL || 
  66.      b->mesh->nu != b->nu ||
  67.      b->mesh->nv != b->nv) || 
  68.     (b->flag & BEZ_REMESH)) BezierReDice(b);
  69.     if (b->geomflags & VERT_4D) fourd = 1;
  70.     return(AnyToPL((Geom *)b->mesh, T));
  71.   }
  72.  
  73.   /*
  74.    * Quad to PolyList 
  75.    */ 
  76.   if (!strcmp(oldtype, "quad")) {
  77.     Quad *o = (Quad *)old;
  78.     
  79.     /* Copy vertices */
  80.     point4 = (HPoint3 *)OOG_NewE(o->maxquad * 4 * sizeof(HPoint3), msg);
  81.     for (i = 0; i < o->maxquad; i ++) 
  82.       for (j = 0; j < 4; j++) HPt3Copy(&o->p[i][j], &point4[(i*4) + j]);
  83.     
  84.     /* Copy the colors if necessary. */
  85.     if (o->flag & QUAD_C) {
  86.       flags |= PL_HASVCOL;
  87.       color = (ColorA *)OOG_NewE(o->maxquad * 4 * sizeof(ColorA), msg);
  88.       for (i = 0; i < o->maxquad; i++)
  89.     for (j = 0; j < 4; j++)
  90.       bcopy(&o->c[i][j], &color[(i*4) + j], sizeof(ColorA));
  91.     }
  92.  
  93.     /* Copy the normals if necessary. */
  94.     if (o->flag & QUAD_N) {
  95.       flags |= PL_HASVN;
  96.       normal = (Point3 *)OOG_NewE(o->maxquad * 4 * sizeof(Point3), msg);
  97.       for (i = 0; i < o->maxquad; i++)
  98.     for (j = 0; j < 4; j++) Pt3Copy(&o->n[i][j], &normal[(i*4) + j]);
  99.     }
  100.     
  101.     /* Create the polygons. */
  102.     nvert = (int *)OOG_NewE(o->maxquad * sizeof(int), msg);
  103.     vert = (int *)OOG_NewE(o->maxquad * 4 * sizeof(int), msg);
  104.     for (i = 0; i < o->maxquad; i++) {
  105.       nvert[i] = 4; 
  106.       for (j = 0; j < 4; j++) vert[(i*4) + j] = (i*4) + j;
  107.     }
  108.  
  109.     if (o->geomflags & VERT_4D) fourd = 1;
  110.     
  111.     npoly = o->maxquad;
  112.         
  113.   }
  114.   
  115.   
  116.   /* 
  117.    * Mesh to PolyList
  118.    */
  119.   if (!strcmp(oldtype, "mesh")) {
  120.     Mesh *m = (Mesh *)old;
  121.     
  122.     /* Copy vertices. */
  123.     point4 = m->p;
  124.     
  125.     /* Copy the colors. */
  126.     if (m->flag & MESH_C) {
  127.       flags |= PL_HASVCOL;
  128.       color = m->c;
  129.     }
  130.  
  131.     /* Copy the normals */
  132.     if (m->flag & MESH_N) {
  133.       flags |= PL_HASVN;
  134.       normal = m->n;
  135.     }
  136.  
  137.     /* Create the polygons. */
  138.     npoly = m->nu * m->nv;
  139.     nvert = (int *)OOG_NewE(npoly * sizeof(int), msg);
  140.     vert = (int *)OOG_NewE(npoly * 4 * sizeof(int), msg);
  141.     for (i = 0; i < m->nv - 1; i++) 
  142.       for (j = 0; j < m->nu - 1; j++) {
  143.     nvert[i * (m->nu - 1) + j] = 4;
  144.     vert[(i * (m->nu - 1) + j) * 4] = i * m->nu + j;
  145.     vert[(i * (m->nu - 1) + j) * 4 + 1] = i * m->nu + j + 1;
  146.     vert[(i * (m->nu - 1) + j) * 4 + 2] = (i + 1) * m->nu + j + 1;
  147.     vert[(i * (m->nu - 1) + j) * 4 + 3] = (i + 1) * m->nu + j;
  148.       }
  149.     /* Do the wrapping if necessary. */
  150.     npoly = (m->nu - 1) * (m->nv - 1);
  151.     if (m->flag & MESH_UWRAP) {
  152.       j = m->nu - 1;
  153.       for (i = 0; i < m->nv - 1; i++) {
  154.     nvert[npoly] = 4;
  155.     vert[npoly * 4] = i * m->nu + j;
  156.     vert[npoly * 4 + 1] = i * m->nu;
  157.     vert[npoly * 4 + 2] = (i + 1) * m->nu;
  158.     vert[npoly++ * 4 + 3] = (i + 1) * m->nu + j;
  159.       }
  160.     }
  161.     if (m->flag & MESH_VWRAP) {
  162.       i = m->nv - 1;
  163.       for (j = 0; j < m->nu - 1; j++) {
  164.     nvert[npoly] = 4;
  165.     vert[npoly * 4] = i * m->nu + j;
  166.     vert[npoly * 4 + 1] = i *m->nu + j + 1;
  167.     vert[npoly * 4 + 2] = j + 1;
  168.     vert[npoly++ * 4 + 3] = j;
  169.       }
  170.     }
  171.     if (m->flag & MESH_UWRAP && m->flag & MESH_VWRAP) {
  172.       nvert[npoly] = 4;
  173.       vert[npoly * 4] = m->nu * m->nv - 1;
  174.       vert[npoly * 4 + 1] = (m->nv - 1) * m->nu;
  175.       vert[npoly * 4 + 2] = 0;
  176.       vert[npoly++ * 4 + 3] = m->nu - 1; 
  177.     }
  178.  
  179.     if (m->geomflags & VERT_4D) fourd = 1;
  180.  
  181.   }
  182.   
  183.   
  184.   
  185.   /* 
  186.    * Vect to PolyList
  187.    */
  188.   if (!strcmp(oldtype, "vect")) {
  189.     Vect *v = (Vect *)old;
  190.     
  191.     /* Copy points. */
  192.     point4 = v->p;
  193.  
  194.     /* Copy colors. */
  195.     if (v->ncolor) {
  196.       flags |= PL_HASVCOL;
  197.       color = OOGLNewNE(ColorA, 2 * v->nvert, msg);
  198.       for (g = h = i = 0; h < v->nvec; h++) {
  199.     if (h && v->vncolor[h]) i++;
  200.     for (j = k = 0; j < abs(v->vnvert[h]); j++) {
  201.       bcopy(&v->c[i + k], &color[g++], sizeof(ColorA));
  202.       if (k + 1 < v->vncolor[h]) k++;
  203.     }
  204.     i += k;
  205.       }
  206.     }
  207.     
  208.     /* Create polygons to connect the points. */
  209.     nvert = (int *)OOG_NewE(v->nvert * sizeof(int), msg);
  210.     for (i = 0; i < v->nvert; i++) nvert[i] = 2;
  211.     vert = (int *)OOG_NewE(v->nvert * 2 * sizeof(int), msg);
  212.     for (h = i = k = 0; i < v->nvec; i++) {
  213.       for (j = 0; j < abs(v->vnvert[i]);) {
  214.     vert[h++] = k+j++;
  215.     vert[h++] = k+j;
  216.       }
  217.       if (j) h -= 2;
  218.       if (v->vnvert[i] < 0) {
  219.     vert[h++] = k;
  220.     vert[h++] = k+j-1;
  221.       }
  222.       k += j;
  223.     }
  224.  
  225.     npoly = h/2;
  226.     
  227.     if (v->geomflags & VERT_4D) fourd = 1;
  228.  
  229.   }
  230.     
  231.  
  232.   /* 
  233.    * List to PolyList
  234.    */
  235.   if (!strcmp(oldtype, "list") || !strcmp(oldtype, "bezierlist")) {
  236.     List *l = (List *)old;
  237.     Geom *a, *b;
  238.     
  239.     new = (PolyList *)PLCombine(a = AnyToPL((Geom *)l->car, T), 
  240.                 b = AnyToPL((Geom *)l->cdr, T));
  241.     GeomDelete(a);
  242.     GeomDelete(b);
  243.  
  244.     transpts = 0;
  245.  
  246.     if (l->geomflags & VERT_4D) fourd = 1;
  247.     
  248.   }
  249.   
  250.     
  251.   /* 
  252.    * DiscGrp to PolyList
  253.    */
  254.   if (!strcmp(oldtype, "discgrp") ) {
  255.     DiscGrp *dg = (DiscGrp *)old;
  256.     Geom *geom = NULL, *geom2;
  257.     PolyList *a = NULL, *b = NULL, *c = NULL, *d = NULL;
  258.     Transform Tnew, Tnew2;
  259.     
  260.     if (dg->geom) geom = dg->geom;
  261.     else if (dg->ddgeom) geom = dg->ddgeom;
  262.     else geom = DiscGrpDirDom(dg);
  263.     a = (PolyList *) AnyToPL(geom, TM_IDENTITY);
  264.     b = (PolyList *) GeomCopy( (Geom *) a);
  265.     if (dg->camgeom) 
  266.     {
  267.         c = (PolyList *) AnyToPL(geom, TM_IDENTITY);
  268.     d = (PolyList *) GeomCopy( (Geom *) c);
  269.     }
  270.  
  271.     /* this isn'tgoing to be right as long as appearances aren't respected.
  272.     The dirichlet domain code (see /u/gcg/ngrap/src/lib/gprim/discgrp/dgdraw.c)
  273.     has to resort to applying appearances in its inner loop in order to get
  274.     the large copy to be drawn as edges only, and the inner as faces.
  275.     That file shows what the reasonable behaviour should be if 
  276.     appearances were respected (see the #ifdef REASONABLE code). */
  277.  
  278.     /* the DiscGrp object should support the GeomIterate construct, but
  279.     it doesn't */
  280.     for (i=0; i<dg->big_list->num_el; ++i)
  281.     {
  282.       TmConcat(dg->big_list->el_list[i].tform, T, Tnew); 
  283.       PLTransformInto(a, b, Tnew);
  284.       new = (PolyList *)PLCombine((Geom *)new, (Geom *)b);
  285.       /* maybe need to draw the camera too */
  286.       if (dg->flag & DG_CENTERCAM && dg->camgeom)    {
  287.         TmConcat(dg->c2m, Tnew, Tnew2);
  288.         PLTransformInto(c, d, Tnew);
  289.         new = (PolyList *)PLCombine((Geom *)new, (Geom *)d);
  290.     }
  291.     }
  292.     if (a) GeomDelete((Geom *)a);
  293.     if (b) GeomDelete((Geom *)b);
  294.     if (c) GeomDelete((Geom *)c);
  295.     if (d) GeomDelete((Geom *)d);
  296.  
  297.     transpts = 0;
  298.  
  299.     if (dg->geomflags & VERT_4D) fourd = 1;
  300.     
  301.   }
  302.   
  303.     
  304.   /* 
  305.    * Inst to PolyList 
  306.    */
  307.   if (!strcmp(oldtype, "inst")) {
  308.     Inst *inst = (Inst *)old;
  309.     Transform Tnew;
  310.     GeomIter *it;
  311.     PolyList *a, *b;
  312.     
  313.     a = (PolyList *)AnyToPL(inst->geom, TM_IDENTITY);
  314.     b = (PolyList *)GeomCopy((Geom *)a);
  315.     it = GeomIterate((Geom *)inst, DEEP);
  316.     while (NextTransform(it, Tnew)) {
  317.       TmConcat(Tnew, T, Tnew); 
  318.       PLTransformInto(a, b, Tnew);
  319.       new = (PolyList *)PLCombine((Geom *)new, (Geom *)b);
  320.     }
  321.     GeomDelete((Geom *)a);
  322.     GeomDelete((Geom *)b);
  323.  
  324.     transpts = 0;
  325.  
  326.     if (inst->geomflags & VERT_4D) fourd = 1;
  327.  
  328.   }
  329.     
  330.   /* Create the new object */
  331.   if (new == NULL && npoly) new = (PolyList *) 
  332.     GeomCreate("polylist", 
  333.            CR_NPOLY, npoly,
  334.            CR_POINT4, point4,
  335.            CR_COLOR, color,
  336.            CR_NORMAL, normal,
  337.            CR_NVERT, nvert,
  338.            CR_VERT, vert,
  339.            CR_FLAG, flags,
  340.            CR_4D, fourd,
  341.            CR_END);
  342.  
  343.   if (strcmp(oldtype, "mesh")) {
  344.     if (strcmp(oldtype, "vect") && point4 != NULL) OOGLFree(point4);
  345.     if (color != NULL) OOGLFree(color);
  346.     if (nvert != NULL) OOGLFree(nvert);
  347.     if (vert != NULL) OOGLFree(vert);
  348.   }
  349.  
  350.   if (new == NULL) return NULL;
  351.   
  352.   /* Apply the transformation. */
  353.   if (transpts) 
  354.     for (i = 0; i < new->n_verts; i++) {
  355.       HPt3Transform(T, &new->vl[i].pt, &new->vl[i].pt);
  356.       if (!(new->geomflags & VERT_4D))
  357.     HPt3Dehomogenize(&new->vl[i].pt, &new->vl[i].pt);
  358.     }
  359.  
  360.   return((Geom *)new);
  361.   
  362. }
  363.  
  364.  
  365. /* 
  366.  * This routine transforms the points of src and places them in dest, 
  367.  * which had better be exactely the same size. 
  368.  */
  369. void PLTransformInto(PolyList *src, PolyList *dest, Transform T) {
  370.   if (src == NULL || dest == NULL) return;
  371.   bcopy(src->vl, dest->vl, src->n_verts * sizeof(Vertex));
  372.   GeomTransform((Geom *)dest, T);
  373. }
  374.